package sk.ygor.raynor.rebind.serializable


import base.JSONSerializerBaseTypeGenerator
import collections.JSONSerializerCollectionTypeGenerator
import generic.JSONSerializerGenericTypeGenerator
import com.google.gwt.core.ext.typeinfo.JType
import com.google.gwt.core.ext.{UnableToCompleteException, GeneratorContext, TreeLogger, Generator}
import java.lang.String

class JSONSerializableGenerator extends Generator {
  case class InputContext(logger: TreeLogger, context: GeneratorContext, inputType: JType)

  // inherited generator method
  def generate(logger: TreeLogger, context: GeneratorContext, inputClassName: String): String = {
    generate(logger, context, context.getTypeOracle().getType(inputClassName));
  }

  def generate(logger: TreeLogger, context: GeneratorContext, jType: JType): String = {
    try {
      generateSerializerClass(InputContext(logger, context, jType));
    } catch {
      case e => {
        logger.log(TreeLogger.ERROR, "Generator ERROR!!!", e);
        throw new UnableToCompleteException();
      }
    }
  }

  private def generateSerializerClass(inputContext: InputContext): String = {
    val structureInfo = JSONSerializableAnalysis.getStructureInfo(inputContext.inputType)
    structureInfo match {
      case x@BaseTypeStructureInfo(_, _) => JSONSerializerBaseTypeGenerator.generate(x)
      case x@CollectionTypeStructureInfo(_, _) => JSONSerializerCollectionTypeGenerator.generate(inputContext.logger, inputContext.context, x)
      case x@GenericTypeStructure(_, _, _) => JSONSerializerGenericTypeGenerator.generate(inputContext.logger, inputContext.context, x)
    }
    structureInfo.dependendTypes.foreach(remainingType => {
            new JSONSerializableGenerator().generate(inputContext.logger, inputContext.context, remainingType)
    })
    structureInfo.serializer.fullName
  }

}
